package martian.t1me
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	
	import martian.t1me.core.Group;
	import martian.t1me.core.Sequencable;
	import martian.t1me.core.Sequence;

	public class Library extends EventDispatcher implements Sequencable
	{
		static public const PROGRESS:String = "libraryEventProgress";
		
		
		
		private var raws:Array;
			public function get assets():Array { return raws; }
		
		private var loader:Load;
		private var feed:XML;
		private var sequence:Sequence;	
			public var loading:Number = 0;
			public function get index():int { return sequence.index; }
			public function get current():Load { return (sequence.current as Load); }
		
		public function Library(feed:*, cache:Boolean = false, proxy:Boolean = false)
		{
			raws = new Array();
			
			if (feed is String || feed is URLRequest)
			{
				loader = new Load(feed, Load.TEXT, cache, proxy);
					loader.addEventListener(Event.COMPLETE, parse);
			}
			else if (feed is XML) { this.feed = feed; }
			else { throw new ArgumentError("Wrong argument : feed"); }
			
			sequence = new Sequence();
				sequence.addEventListener(Sequence.STEP, step);
				sequence.addEventListener(Sequence.STOP, stop);
		}
		
		private function data(e:Event):void
		{
			feed = XML(e.target.data);
			parse(feed);
		}
		
		private function parse(xml:XML):void
		{
			var children:XMLList = xml.children(),
				url:String, type:String, cache:Boolean, proxy:Boolean, load:Load;
			
			for each (var child:XML in children)
			{
				url = String(child.valueOf());
				type = String(child.name()).toLowerCase();
				cache = String(child.@cache).toLowerCase() == "true";
				proxy = String(child.@proxy).toLowerCase() == "true";
				
				load = new Load(url, type, cache, proxy);
					load.addEventListener(ProgressEvent.PROGRESS, progress);
					load.addEventListener(Event.COMPLETE, complete);
					
				sequence.stack.push(load);
			}

			sequence.start();
		}
		
		private function progress(e:ProgressEvent):void
		{
			//INFO for some reasons i dont know about yet, bytesTotal can progress too so this value is kinda wrong
			loading = (sequence.index + (e.bytesLoaded / e.bytesTotal)) / sequence.stack.length;
			dispatchEvent(new Event(PROGRESS));
		}
		
		private function complete(e:Event):void
		{
			e.target.removeEventListener(ProgressEvent.PROGRESS, progress);
			e.target.removeEventListener(Event.COMPLETE, complete);
		}
		
		private function step(e:Event):void { dispatchEvent(e.clone()); }
		
		public function start():void
		{
			if (loader != null)	{ loader.start(); }
			else { parse(feed); }
		}
		private function stop(e:Event):void
		{
			for each (var asset:Sequencable in sequence.stack) { raws.push((asset as Load).data); }
			dispatchEvent(new Event(Event.COMPLETE));
			dispatchEvent(new Event(Sequence.STOP));
		}
	}
}